import * as PIXI from "../../../libs/pixi.4.8.0";
import AssetsBundle from "./AssetsBundle";
import AssetsBundleEvent from "./AssetsBundleEvent";
import {pool} from "../base/Pool";

/**
 *
 * @type {PIXI.loaders.Loader}
 * @private
 */
let _resLoader = new PIXI.loaders.Loader('', 6);

/**
 * 等待加载的资源包
 * @type {Array}
 * @private
 */
let _waitBundles = [];

/**
 *
 * @type {AssetsBundle}
 * @private
 */
let _currentBundle = null;

/**
 * 资源加载器是否闲置
 * @type {boolean}
 * @private
 */
let _resLoaderIdle = true;

/**
 *
 * @private
 */
function _loadAssetBundle() {
    if (_resLoaderIdle) {
        _currentBundle = _waitBundles.shift();
        if (_currentBundle) {
            _resLoaderIdle = false;
            _resLoader.progress = 0;
            _resLoader.loading = false;

            let count = 0;
            let res = _currentBundle.getAssets();
            res.map(item => {
                if (!_resLoader.resources[item.name]) {
                    _resLoader.add(item.name, item.url, item.options, item.cb);
                    count++;
                }
            });
            if (count > 0) {
                _resLoader.onError.once(_onLoadAssetError);
                _resLoader.onComplete.once(_onLoadAssetComplete);
                _resLoader.onProgress.add(_onLoadAssetProgress);

                let beforeMiddleware = _currentBundle.getBeforeMiddleware();
                if (beforeMiddleware) {
                    _resLoader.pre(beforeMiddleware);
                }

                let afterMiddleware = _currentBundle.getAfterMiddleware();
                if (afterMiddleware) {
                    _resLoader.use(afterMiddleware);
                }
                _resLoader.load();
            } else {
                _onLoadAssetComplete(_resLoader, _resLoader.resources);
            }
        }
    }
}

/**
 *
 * @param e
 * @private
 */
function _onLoadAssetError(errMsg, loader, res) {
    if (_currentBundle) {
        let evt = pool.getItemByClass('AssetsBundleEvent', AssetsBundleEvent);
        evt.type = AssetsBundleEvent.ERROR;
        evt.data = {
            name: res.name,
            url: res.url
        };
        _currentBundle.dispatchEvent(evt);
        evt.dispose();
        pool.recover('AssetsBundleEvent', evt);
    }
    if (res.texture) {
        res.texture.destroy(true);
    }
    delete loader.resources[res.name];
    res = null;
}

/**
 *
 * @param e
 * @private
 */
function _onLoadAssetProgress(loader, res) {
    if (_currentBundle) {
        let evt = pool.getItemByClass('AssetsBundleEvent', AssetsBundleEvent);
        evt.type = AssetsBundleEvent.PROGRESS;
        evt.data = {
            progress: loader.progress
        };
        _currentBundle.progress = Math.round(loader.progress);
        _currentBundle.dispatchEvent(evt);
        evt.dispose();
        pool.recover('AssetsBundleEvent', evt);
    }
}

/**
 *
 * @param e
 * @private
 */
function _onLoadAssetComplete(loader, resources) {
    if (_currentBundle) {
        let evt = pool.getItemByClass('AssetsBundleEvent', AssetsBundleEvent);
        evt.type = AssetsBundleEvent.COMPLETE;
        evt.data = resources;
        _currentBundle.progress = 1;
        _currentBundle.dispatchEvent(evt);
        evt.dispose();
        pool.recover('AssetsBundleEvent', evt);
    }
    _resLoaderIdle = true;
    _loadAssetBundle();
}

/**
 *
 * @param {dbook.resManager.AssetsBundle} bundle
 * @returns {Promise<any>}
 */
export function loadAssetBundle (bundle) {
    if (_waitBundles.indexOf(bundle) === -1) {
        _waitBundles.push(bundle);
    }
    _loadAssetBundle();
}
